#include "surface.h"
#include "animation.h"

namespace SEL
{

Animation::Frame::Frame (Surface *surface, Uint32 duration)
    : m_surface (surface), m_duration (duration)
{
	if (m_surface)
		m_surface->ref ();
}

Animation::Frame::~Frame ()
{
	releaseSurface ();
}

void
Animation::Frame::setSurface (Surface *surface)
{
	releaseSurface ();
	if (surface)
	{
		m_surface = surface;
		m_surface->ref ();
	}
}

void
Animation::Frame::releaseSurface ()
{
	if (m_surface)
	{
		m_surface->unref ();
		m_surface = NULL;
	}
};

void
Animation::Frame::setDuration (Uint32 duration)
{
	m_duration = duration;
}

Animation::Frame &
Animation::Frame::operator= (Animation::Frame & frame)
{
	setSurface (frame.surface ());
	setDuration (frame.duration ());
	return *this;
}

Animation::Animation ()
	: m_loop_count (-1), m_position (0)
{ }

Animation::~Animation ()
{ }

void
Animation::addFrame (Animation::Frame & frame)
{
	m_frames.push_back (frame);
}

void
Animation::insertFrame (Animation::Frame & frame, int pos)
{
	m_frames.insert (Frame::List::iterator (&m_frames [pos]), frame);
}

void
Animation::removeFrame (int index)
{
	m_frames.erase (Frame::List::iterator (&m_frames [index]));
}

void
Animation::removeFrame (Animation::Frame & frame)
{
	m_frames.erase (Frame::List::iterator (&frame));
}

void
Animation::generateOrder (Animation::OrderType type)
{
	m_order.clear ();

	if (type == OrderForward || type == OrderPingPong)
	{
		for (unsigned int i = 0; i < m_frames.size (); i++)
		{
			m_order.push_back (i);
		}
	}
	if (type == OrderBackward || type == OrderPingPong)
	{
		for (unsigned int i = m_frames.size (); i > 0; i--)
		{
			m_order.push_back (i-1);
		}
	}
}

void
Animation::setOrder (const Order & order)
{
	m_order = order;
};

void
Animation::toBegin ()
{
	m_position = 0;
}

void
Animation::toEnd ()
{
	m_position = m_order.size ();
	if (m_position > 0)
		-- m_position;
}

void
Animation::prev (bool loop)
{
	if (m_position > 0)
		-- m_position;
	else
	{
		if (loop)
		{
			toEnd ();
			if (m_loop_count > 0)
				m_loop_count --;
		}
		else
		{
			m_position = 0;
		}
	}
}

void
Animation::next (bool loop)
{
	++ m_position;
	if (m_position >= m_order.size ())
	{
		if (loop)
		{
			toBegin ();
			if (m_loop_count > 0)
				m_loop_count --;
		}
		else
		{
			m_position = m_order.size () - 1;
		}
	}
}

void
Animation::go (unsigned int position)
{
	m_position = position;
}

void
Animation::setLoopCount (int loop_count)
{
	m_loop_count = loop_count;
}


} // namespace SEL
